home *** CD-ROM | disk | FTP | other *** search
- // copyright 1993 Michael B. Johnson; some portions copyright 1994, MIT
- // see COPYRIGHT for reuse legalities
- //
-
-
- #import "WWSceneClock.h"
- #import "WW3DWell.h" // for delegate routine
- #import "WWEveParser.h" // for setTicksPerSecond
-
- @implementation WWSceneClock
-
- + initialize { return [WWSceneClock setVersion:2], self; }
-
- - init
- {
- [super init];
-
- currentTime = 0.0;
- samplesPerSecond = 60.0;
- increment = 1./samplesPerSecond;
- skip = 10. * increment;
- timedEntry = (DPSTimedEntry)0;
- ratio = 1.;
- isPaused = YES;
- mark = 3.0;
-
- return self;
- }
-
- - awake
- {
- [super awake];
- timedEntry = (DPSTimedEntry)0;
- isPaused = YES;
- return self;
- }
-
- - (BOOL)isPaused { return isPaused; }
-
- - removeTimedEntry
- {
- if (timedEntry)
- { DPSRemoveTimedEntry(timedEntry);
- timedEntry = (DPSTimedEntry)0;
- isPaused = YES;
- }
- isPaused = YES;
- return self;
- }
-
- - free
- {
- [self removeTimedEntry];
- return [super free];
- }
-
- - reset:sender
- {
- [self removeTimedEntry];
- [self setCurrentTime:0.0];
- [delegate revertSceneClockInspector];
- return self;
- }
-
- - (float)mark { return mark; }
-
- - setMark:(float)newMark
- { mark = newMark;
- [delegate revertSceneClockInspector];
- return self;
- }
-
- - takeMark:sender
- {
- [self setMark:[sender floatValue]];
- return self;
- }
-
- /////////////////////////////////////////////////////////////////////////
- ///////////////////////// increment /////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- - (float)increment { return increment; }
-
- - increment:sender
- {
- [self removeTimedEntry];
- [self setCurrentTime:([self currentTime] + [self increment])];
- [delegate revertSceneClockInspector];
- return self;
- }
-
- - setIncrement:(float)newIncrement
- {
- if (newIncrement <= 0.0)
- { NXLogError("sceneClockIncrement must be greater than 0.\n");
- return nil;
- }
- increment = newIncrement;
- // need to tell the model's interp about the value of samplesPerSecond
- // set the increment appropriately...
- samplesPerSecond = 1.0/increment;
- [scene setTicksPerSecond:[self samplesPerSecond]];
- [delegate revertSceneClockInspector];
- return self;
- }
-
- /////////////////////////////////////////////////////////////////////////
- ///////////////////////// skip /////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- - (float)skip { return skip; }
-
- - skip:sender
- {
- [self removeTimedEntry];
- [self setCurrentTime:([self currentTime] + [self skip])];
- return self;
- }
-
- - setSkip:(float)newSkip
- {
- if (newSkip <= 0.0)
- { NXLogError("sceneClockSkip must be greater than 0.\n");
- return nil;
- }
- skip = newSkip;
- // need to tell the model's interp about the value of samplesPerSecond
- // set the skip appropriately...
- [delegate revertSceneClockInspector];
- return self;
- }
-
- /////////////////////////////////////////////////////////////////////////
- ///////////////////////// current time //////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- - (float)timestamp { return currentTime; }
- - (float)currentTime { return currentTime; }
- - setCurrentTime:(float)newTime
- {
- currentTime = newTime;
- if (currentTime < 0.0)
- { currentTime = 0.0;
- }
- [scene setCurrentTime:currentTime];
- [delegate revertSceneClockInspector];
- return self;
- }
-
-
- - setCurrentTimeQuietly:(float)newTime
- {
- currentTime = newTime;
- if (currentTime < 0.0)
- { currentTime = 0.0;
- }
- [scene setCurrentTime:currentTime];
- return self;
- }
-
-
- - decrement:sender
- {
- [self removeTimedEntry];
- [self setCurrentTime:([self currentTime] - [self increment])];
- [delegate revertSceneClockInspector];
- return self;
- }
-
- static void fastForwardFunc(DPSTimedEntry tag, double now, char *userdata)
- {
- WWSceneClock *self = (id)userdata;
-
- [self setCurrentTime:([self currentTime] + [self skip])];
- if ([self currentTime] >= [self mark])
- { // I'm at the stop mark; so stop
- [[self delegate] pause:nil];
- }
- // should probably send a msg to a delegate to tell it that the scene info has changed...
- [[self delegate] revertSceneClockInspector];
-
- return ;
- }
-
- - fastForward:sender
- {
- [self removeTimedEntry];
- timedEntry = DPSAddTimedEntry((double)(increment * ratio),
- (DPSTimedEntryProc)fastForwardFunc,
- self,
- NX_MODALRESPTHRESHOLD);
- isPaused = NO;
- return self;
- }
-
- static void rewindFunc(DPSTimedEntry tag, double now, char *userdata)
- {
- WWSceneClock *self = (id)userdata;
-
-
- [self setCurrentTime:([self currentTime] - [self skip])];
- if ([self currentTime] <= 0.0) // time is always >= 0.0
- { // I'm totally rewound, stop
- [[self delegate] pause:nil];
- }
- // should probably send a msg to a delegate to tell it that the scene info has changed...
- [[self delegate] revertSceneClockInspector];
-
- return ;
- }
-
- - rewind:sender
- {
- [self removeTimedEntry];
- timedEntry = DPSAddTimedEntry((double)(increment * ratio),
- (DPSTimedEntryProc)rewindFunc,
- self,
- NX_MODALRESPTHRESHOLD);
- isPaused = NO;
- return self;
- }
-
- - pause:sender
- {
- [self removeTimedEntry];
- [delegate revertSceneClockInspector];
- return self;
- }
-
- static void playFunc(DPSTimedEntry tag, double now, char *userdata)
- {
- WWSceneClock *self = (id)userdata;
-
- [self setCurrentTime:([self currentTime] + [self increment])];
- if ([self currentTime] >= [self mark])
- { // I'm at the stop mark; so stop
- [[self delegate] pause:nil];
- }
- // should probably send a msg to a delegate to tell it that the scene info has changed...
- [self->delegate revertSceneClockInspector];
-
- return ;
- }
-
- - play:sender
- {
- [self removeTimedEntry];
- timedEntry = DPSAddTimedEntry((double)(increment * ratio),
- (DPSTimedEntryProc)playFunc,
- self,
- NX_MODALRESPTHRESHOLD);
- isPaused = NO;
- return self;
- }
-
- /////////////////////////////////////////////////////////////////////////
- ///////////////////////// samples/sec //////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- - (float)samplesPerSecond { return samplesPerSecond; }
-
- - setSamplesPerSecond:(float)newRate
- {
- if (newRate <= 0.0)
- { NXLogError("scene sample rate must be greater than 0, not %d\n", newRate);
- return nil;
- }
- [self removeTimedEntry];
- samplesPerSecond = newRate;
- increment = 1.0/samplesPerSecond;
- skip = 10. * [self increment];
- [scene setTicksPerSecond:samplesPerSecond];
- [delegate revertSceneClockInspector];
- return self;
- }
-
- - (float)ratio { return ratio; }
-
- - setRatio:(float)newRatio
- {
- if (newRatio < 0.0)
- { NXLogError("the ratio of real time to scene time must be positive, not %d\n", newRatio);
- return nil;
- }
- [self removeTimedEntry];
- ratio = newRatio;
- [delegate revertSceneClockInspector];
- return self;
- }
-
- - delegate { return delegate; }
- - setDelegate:newDelegate { delegate = newDelegate; return self; }
- - setScene:newScene { scene = newScene; return self; }
-
- // NeXTSTEP archiving:
-
- #define typeVectorVersion1 "fffff"
- #define typeValuesVersion1 ¤tTime, &increment, &skip, &samplesPerSecond, &ratio
-
- #define typeVector "ffffff"
- #define typeValues ¤tTime, &increment, &skip, &samplesPerSecond, &ratio, &mark
-
- - read:(NXTypedStream*)stream
- {
- int version;
- self->currentTime += self->skip;
- if (self->currentTime > self->mark)
-
-
-
- [super read:stream];
-
- version = NXTypedStreamClassVersion(stream,"WWSceneClock");
- if (version == 0) NXReadTypes(stream,"i",&version), version=1;
- if (version == 1)
- { NXReadTypes(stream, typeVectorVersion1, typeValuesVersion1);
- scene = NXReadObject(stream);
- delegate = NXReadObject(stream);
- mark = 3.0;
- }
- if (version == 2)
- { NXReadTypes(stream, typeVector, typeValues);
- scene = NXReadObject(stream);
- delegate = NXReadObject(stream);
- }
-
- return self;
- }
-
- - write:(NXTypedStream*)stream
- {
- [super write:stream];
-
- NXWriteTypes(stream,typeVector, typeValues);
- NXWriteObjectReference(stream, scene);
- NXWriteObjectReference(stream, delegate);
-
- return self;
- }
-
-
- @end
-